#include "WidgetMovimiento.h"
#include "../common/utils/FileChecker.h"
#include "../common/lib/SDL_rotozoom.h"

WidgetMovimiento::WidgetMovimiento() {
}

WidgetMovimiento::WidgetMovimiento(int posX, int posY, Widget *parent):Widget(posX, posY, parent) {
}

WidgetMovimiento::~WidgetMovimiento() {
}

void WidgetMovimiento::surfaceReflection(SDL_Surface* objectSurface, SDL_Surface* screenSurface) {

	int screenWidth = screenSurface->w;
	int screenHeight = screenSurface->h;
	int objectWidth = objectSurface->w;
	int objectHeight = objectSurface->h;

	int topBorderIntersection = analyseBorderIntersection(TOP_BORDER, objectWidth, objectHeight, screenWidth, screenHeight);
	int bottomBorderIntersection = analyseBorderIntersection(BOTTOM_BORDER, objectWidth, objectHeight, screenWidth, screenHeight);
	int leftBorderIntersection = analyseBorderIntersection(LEFT_BORDER,	objectWidth, objectHeight, screenWidth, screenHeight);
	int rightBorderIntersection = analyseBorderIntersection(RIGHT_BORDER, objectWidth, objectHeight, screenWidth, screenHeight);

	// Position where the surface will be draw
	SDL_Rect posRectAux = { parcel.posX, parcel.posY, objectSurface->w,
			objectSurface->h };

	// Position fixed to the center of rotation
	posRectAux.x -= (objectSurface->w) / 2;
	posRectAux.y -= (objectSurface->h) / 2;

	//If the object is going out through the LEFT BORDER -> the object reflection will be analyzed
	if (leftBorderIntersection >= 0) {
		// If half object is over the left border the other half will be reflected on the right border
		if (leftBorderIntersection == 1) {
			SDL_Rect posRectCopy = posRectAux;
			posRectCopy.x += screenWidth;
			SDL_BlitSurface(objectSurface, NULL, screenSurface, &posRectCopy);

			if (topBorderIntersection == 1) {
				SDL_Rect posRectCopy = posRectAux;
				posRectCopy.x += screenWidth;
				posRectCopy.y += screenHeight;
				SDL_BlitSurface(objectSurface, NULL, screenSurface,
						&posRectCopy);
			} else if (bottomBorderIntersection == 1) {
				SDL_Rect posRectCopy = posRectAux;
				posRectCopy.x += screenWidth;
				posRectCopy.y -= screenHeight;
				SDL_BlitSurface(objectSurface, NULL, screenSurface,
						&posRectCopy);
			}
		} else
			parcel.posX += screenWidth;
	}
	//If the object is going out through the RIGHT BORDER -> the object reflection will be analyzed
	if (rightBorderIntersection >= 0) {
		if (rightBorderIntersection == 1) {
			SDL_Rect posRectCopy = posRectAux;
			posRectCopy.x -= screenWidth;
			SDL_BlitSurface(objectSurface, NULL, screenSurface, &posRectCopy);
			if (topBorderIntersection == 1) {
				SDL_Rect posRectCopy = posRectAux;
				posRectCopy.x -= screenWidth;
				posRectCopy.y += screenHeight;
				SDL_BlitSurface(objectSurface, NULL, screenSurface,
						&posRectCopy);
			} else if (bottomBorderIntersection == 1) {
				SDL_Rect posRectCopy = posRectAux;
				posRectCopy.x -= screenWidth;
				posRectCopy.y -= screenHeight;
				SDL_BlitSurface(objectSurface, NULL, screenSurface,
						&posRectCopy);
			}
		} else
			parcel.posX -= screenWidth;
	}
	//If the object is going out through the TOP BORDER -> the object reflection will be analyzed
	if (topBorderIntersection >= 0) {
		// If half object is over the top border the other half will be reflected on the bottom border
		if (topBorderIntersection == 1) {
			SDL_Rect posRectCopy = posRectAux;
			posRectCopy.y += screenHeight;
			SDL_BlitSurface(objectSurface, NULL, screenSurface, &posRectCopy);
		} else
			parcel.posY += screenHeight;
	}
	//If the object is going out through the BOTTOM BORDER -> the object reflection will be analyzed
	if (bottomBorderIntersection >= 0) {
		// If half object is over the bottom border the other half will be reflected on the top border
		if (bottomBorderIntersection == 1) {
			SDL_Rect posRectCopy = posRectAux;
			posRectCopy.y -= screenHeight;
			SDL_BlitSurface(objectSurface, NULL, screenSurface, &posRectCopy);
		} else
			parcel.posY -= screenHeight;
	}
}

int WidgetMovimiento::analyseBorderIntersection(borderType border, int surfaceWidth, int surfaceHeight, int screenWidth, int screenHeight) {
	int result = -1;
	int surfacePosY = parcel.posY - surfaceHeight / 2;
	int surfacePosX = parcel.posX - surfaceWidth / 2;
	switch (border) {
	case TOP_BORDER: {
		//If the dot is going out through the top border the dot reflection will be analyzed
		if (surfacePosY < 0) {
			// If half dot is over the top border the other half will be reflected on the bottom border
			if (surfacePosY + surfaceHeight > 0)
				result = 1;
			else
				result = 0;
		}
	}
		break;
	case BOTTOM_BORDER: {
		//If the dot is going out through the bottom border the dot reflection will be analyzed
		if (surfacePosY + surfaceHeight > screenHeight) {
			// If half dot is over the bottom border the other half will be reflected on the top border
			if (surfacePosY < screenHeight)
				result = 1;
			else
				result = 0;
		}
	}
		break;
	case RIGHT_BORDER: {
		//If the dot is going out through the right border the dot reflection will be analyzed
		if (surfacePosX + surfaceWidth > screenWidth) {
			// If half dot is over the right border the other half will be reflected on the left border
			if (surfacePosX < screenWidth)
				result = 1;
			else
				result = 0;
		}
	}
		break;
	case LEFT_BORDER: {
		//If the dot is going out through the left border the dot reflection will be analyzed
		if (surfacePosX < 0) {
			// If half dot is over the left border the other half will be reflected on the right border
			if (surfacePosX + surfaceWidth > 0)
				result = 1;
			else
				result = 0;
		}
	}
		break;
	}

	return result;
}

void WidgetMovimiento::showOn(SDL_Surface* surface) {

	surfaceShown = rotozoomSurface(surfaceReference, angle, 1.0,
			SMOOTHING_OFF);

	//Surface Reflection
	surfaceReflection(surfaceShown, surface);

	// Position where the surface will be draw
	SDL_Rect posRect = { parcel.posX, parcel.posY, surfaceShown->w,
			surfaceShown->h };

	// Position fixed to the center of rotation
	posRect.x -= (surfaceShown->w) / 2;
	posRect.y -= (surfaceShown->h) / 2;


	//Show the original dot
	SDL_BlitSurface(surfaceShown, NULL, surface, &posRect);
	SDL_FreeSurface(surfaceShown);
}


